/*
Copyright (C) 2022-2024 Inspur Corp. All Rights Reserved.

SPDX-License-Identifier: Apache-2.0
*/
package sessionmgr

import (
	"icep/common/logger"
	"net/http"
	"strings"
	"sync"

	httputils "icep/common/http"
)

var log = logger.GetLogger("plugins.sessionmgr")

type MemoryMgr struct {
	sessionMap sync.Map
}

func NewMemoryMgr() *MemoryMgr {
	return &MemoryMgr{}
}

type SessionValue struct {
	Token      string     `json:"token"`
	ClientInfo ClientInfo `json:"clientInfo"`
}

type ClientInfo struct {
	IP        string `json:"ip"`
	UserAgent string `json:"userAgent"`
}

func (memMgr *MemoryMgr) Check(userId string, req *http.Request) bool {
	v, isOk := memMgr.sessionMap.Load(userId)
	if !isOk || v == nil {
		return false
	}
	sessV := v.(*SessionValue)
	if sessV == nil {
		log.Errorf("failed to parse value[%v] to *SessionValue", v)
		return false
	}
	reqTk := req.Header.Get("Authorization")
	if strings.HasPrefix(reqTk, "Bearer") || strings.HasPrefix(reqTk, "bearer") {
		reqTk = strings.TrimSpace(reqTk[6:])
	}
	if sessV.Token != reqTk {
		log.Errorf("session token not matched, token=%s", req.Header.Get("Authorization"))
		return false
	}

	ip := httputils.GetRequestIp(req)
	if sessV.ClientInfo.IP != ip || sessV.ClientInfo.UserAgent != req.UserAgent() {
		log.Errorf("session client info changed, ip=%s, user agent=%s", ip, req.UserAgent())
		return false
	}
	return true
}

func (memMgr *MemoryMgr) Add(userId string, token string, req *http.Request) {
	sessV := &SessionValue{
		Token: token,
		ClientInfo: ClientInfo{
			IP:        httputils.GetRequestIp(req),
			UserAgent: req.UserAgent(),
		},
	}
	memMgr.sessionMap.Store(userId, sessV)
}

func (memMgr *MemoryMgr) Remove(userId string) {
	memMgr.sessionMap.Delete(userId)
}
